'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.filterHelperArgs = undefined;

var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');

var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);

exports.filterHelper = filterHelper;

var _mongoid = require('../../types/mongoid');

var _mongoid2 = _interopRequireDefault(_mongoid);

var _utils = require('../../utils');

var _filterOperators = require('./filterOperators');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const filterHelperArgs = exports.filterHelperArgs = (typeComposer, model, opts) => {
  if (!typeComposer || typeComposer.constructor.name !== 'TypeComposer') {
    throw new Error('First arg for filterHelperArgs() should be instance of TypeComposer.');
  }

  if (!model || !model.modelName || !model.schema) {
    throw new Error('Second arg for filterHelperArgs() should be instance of MongooseModel.');
  }

  if (!opts || !opts.filterTypeName) {
    throw new Error('You should provide non-empty `filterTypeName` in options.');
  }

  const removeFields = [];
  if (opts.removeFields) {
    if (Array.isArray(opts.removeFields)) {
      removeFields.push(...opts.removeFields);
    } else {
      removeFields.push(opts.removeFields);
    }
  }

  if (opts.onlyIndexed) {
    const indexedFieldNames = (0, _utils.getIndexedFieldNamesForGraphQL)(model);
    Object.keys(typeComposer.getFields()).forEach(fieldName => {
      if (indexedFieldNames.indexOf(fieldName) === -1) {
        removeFields.push(fieldName);
      }
    });
  }

  const filterTypeName = opts.filterTypeName;
  const itc = typeComposer.getInputTypeComposer().clone(filterTypeName);

  itc.addFields({
    _ids: [_mongoid2.default]
  });

  itc.removeField(removeFields);

  if (opts.requiredFields) {
    itc.makeRequired(opts.requiredFields);
  }

  if (itc.getFieldNames().length === 0) {
    return {};
  }

  (0, _filterOperators.addFilterOperators)(itc, model, opts);

  return {
    filter: {
      type: opts.isRequired ? itc.getTypeNonNull() : itc.getType(),
      description: opts.onlyIndexed ? 'Filter only by indexed fields' : 'Filter by fields'
    }
  };
};
/* eslint-disable no-use-before-define */

function filterHelper(resolveParams) {
  const filter = resolveParams.args && resolveParams.args.filter;
  if (filter && typeof filter === 'object' && Object.keys(filter).length > 0) {
    const modelFields = resolveParams.query.schema.paths;

    const _ids = filter._ids,
          filterFields = (0, _objectWithoutProperties3.default)(filter, ['_ids']);

    if (_ids && Array.isArray(_ids)) {
      // eslint-disable-next-line
      resolveParams.query = resolveParams.query.where({ _id: { $in: _ids } });
    }

    const clearedFilter = {};
    Object.keys(filterFields).forEach(key => {
      if (modelFields[key]) {
        clearedFilter[key] = filterFields[key];
      }
    });
    if (Object.keys(clearedFilter).length > 0) {
      // eslint-disable-next-line
      resolveParams.query = resolveParams.query.where((0, _utils.toMongoDottedObject)(clearedFilter));
    }

    (0, _filterOperators.processFilterOperators)(filter, resolveParams);
  }

  if ((0, _utils.isObject)(resolveParams.rawQuery)) {
    // eslint-disable-next-line
    resolveParams.query = resolveParams.query.where(resolveParams.rawQuery);
  }
}